#include "camera_use.h"


// 创建一个与背景颜色相同的对象来覆盖指定区域
void clear_area(lv_coord_t x, lv_coord_t y, lv_coord_t width, lv_coord_t height, lv_color_t value)
{
    lv_obj_t *clear_obj = lv_obj_create(lv_scr_act());
    lv_obj_remove_style_all(clear_obj);
    lv_obj_set_size(clear_obj, width, height);
    lv_obj_set_pos(clear_obj, x, y);
    lv_obj_set_style_bg_color(clear_obj, value, 0);
    lv_obj_set_style_bg_opa(clear_obj, LV_OPA_COVER, 0);
}

void *ds_ui_page_thread(void *args)
{
    // 确保我们在相机屏幕上创建UI
    lv_scr_load(ui_ScreenCamera);
    
    ui_app_camera(); // 直接启动相机应用
    while (1)
    {
        lv_task_handler();
        usleep(10000); // 增加延迟，减少刷新频率
    }
    return NULL;
}

// void *ds_ui_page_thread(void *args)
// {
//     ui_app_camera(); // 直接启动相机应用
//     while (1)
//     {
//         lv_task_handler();
//         usleep(10000); // 增加延迟，减少刷新频率
//     }
//     return NULL;
// }

// 触摸屏读取回调函数
void touchpad_read(lv_indev_t * indev, lv_indev_data_t * data)
{
    // 使用lv_indev_get_user_data函数获取用户数据，而不是直接访问indev->user_data
    int touch_fd = (int)(uintptr_t)lv_indev_get_user_data(indev);
    struct input_event ev;
    static int x = 0, y = 0;
    static bool pressed = false;
    
    // 读取所有可用的事件
    while (read(touch_fd, &ev, sizeof(ev)) == sizeof(ev)) {
        if (ev.type == EV_ABS) {
            if (ev.code == ABS_X) {
                x = ev.value;
            } else if (ev.code == ABS_Y) {
                y = ev.value;
            }
        } else if (ev.type == EV_KEY) {
            if (ev.code == BTN_TOUCH) {
                pressed = (ev.value == 1);
            }
        }
    }
    
    // 设置数据
    data->point.x = x;
    data->point.y = y;
    data->state = pressed ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
}

// 显示刷新回调函数
void fb_flush(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map)
{
    int fb_fd = (int)(uintptr_t)lv_display_get_driver_data(disp);
    
    // 获取屏幕信息
    struct fb_var_screeninfo vinfo;
    if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo) < 0) {
        perror("Error reading variable screen info");
        lv_display_flush_ready(disp);
        return;
    }

    // 获取固定屏幕信息
    struct fb_fix_screeninfo finfo;
    if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo) < 0) {
        perror("Error reading fixed screen info");
        lv_display_flush_ready(disp);
        return;
    }

    // 计算刷新区域的宽度和高度
    lv_coord_t w = lv_area_get_width(area);
    lv_coord_t h = lv_area_get_height(area);

    // 计算帧缓冲区中的位置
    long location = (area->x1 + vinfo.xoffset) * (vinfo.bits_per_pixel / 8) +
                    (area->y1 + vinfo.yoffset) * finfo.line_length;

    // 映射帧缓冲区内存
    uint8_t *fbp = (uint8_t *)mmap(0, finfo.smem_len, 
                                   PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0);
    if (fbp == MAP_FAILED) {
        perror("Error mapping framebuffer device");
        lv_display_flush_ready(disp);
        return;
    }

    // 根据颜色格式处理像素数据
    if (vinfo.bits_per_pixel == 32) {
        // XRGB8888格式 - 这是您的设备使用的格式
        uint32_t *fb_ptr = (uint32_t *)(fbp + location);
        lv_color_t *lv_ptr = (lv_color_t *)px_map;
        
        for (int y = 0; y < h; y++) {
            for (int x = 0; x < w; x++) {
                // 将LVGL的RGB888转换为XRGB8888
                lv_color_t c = lv_ptr[x + y * w];
                fb_ptr[x + y * (finfo.line_length / 4)] = 
                    (0xFF << 24) | (c.red << 16) | (c.green << 8) | c.blue;
            }
        }
    } else if (vinfo.bits_per_pixel == 16) {
        // RGB565格式
        uint16_t *fb_ptr = (uint16_t *)(fbp + location);
        lv_color_t *lv_ptr = (lv_color_t *)px_map;
        
        for (int y = 0; y < h; y++) {
            for (int x = 0; x < w; x++) {
                // 将LVGL的RGB888转换为RGB565
                lv_color_t c = lv_ptr[x + y * w];
                uint16_t rgb565 = ((c.red & 0xF8) << 8) | ((c.green & 0xFC) << 3) | (c.blue >> 3);
                fb_ptr[x + y * (finfo.line_length / 2)] = rgb565;
            }
        }
    } else if (vinfo.bits_per_pixel == 24) {
        // RGB888格式
        uint8_t *fb_ptr = fbp + location;
        lv_color_t *lv_ptr = (lv_color_t *)px_map;
        
        for (int y = 0; y < h; y++) {
            for (int x = 0; x < w; x++) {
                // LVGL的RGB888直接复制到帧缓冲区
                lv_color_t c = lv_ptr[x + y * w];
                int pixel_offset = (x + y * (finfo.line_length / 3)) * 3;
                fb_ptr[pixel_offset] = c.blue;
                fb_ptr[pixel_offset + 1] = c.green;
                fb_ptr[pixel_offset + 2] = c.red;
            }
        }
    } else {
        printf("Error: Unsupported color format (%d bits per pixel)\n", vinfo.bits_per_pixel);
    }

    // 解除内存映射
    munmap(fbp, finfo.smem_len);

    // 通知LVGL刷新已完成
    lv_display_flush_ready(disp);
}


// 相机使用初始化
void camera_use_init(void)
{
    printf("正在加载相机功能...\n");
    // 确保我们在正确的屏幕上
    lv_scr_load(ui_ScreenCamera);
    
    // 初始化LVGL显示设备
    static lv_display_t *disp;

    // 创建显示对象
    disp = lv_display_create(SCREEN_HOR_RES, SCREEN_VER_RES);
    if (disp == NULL) {
        printf("Failed to create display\n");
        return;
    }

    // 初始化帧缓冲设备
    int fb_fd = open("/dev/fb0", O_RDWR);
    if (fb_fd < 0) {
        perror("Failed to open framebuffer device");
        return;
    }

    // 获取屏幕信息以确定支持的颜色格式
    struct fb_var_screeninfo vinfo;
    if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo) < 0) {
        perror("Error reading variable screen info");
        return;
    }

    // 打印屏幕信息
    printf("fb_var.bits_per_pixel = %d\n", vinfo.bits_per_pixel);
    printf("width = %d, height = %d\n", vinfo.xres, vinfo.yres);

    // 根据硬件支持的颜色格式设置LVGL
    lv_color_format_t color_format;
    if (vinfo.bits_per_pixel == 32) {
        color_format = LV_COLOR_FORMAT_XRGB8888;
        printf("Using XRGB8888 color format\n");
    } else if (vinfo.bits_per_pixel == 24) {
        color_format = LV_COLOR_FORMAT_RGB888;
        printf("Using RGB888 color format\n");
    } else if (vinfo.bits_per_pixel == 16) {
        color_format = LV_COLOR_FORMAT_RGB565;
        printf("Using RGB565 color format\n");
    } else {
        printf("Error: Unsupported color format (%d bits per pixel)\n", vinfo.bits_per_pixel);
        return;
    }

    // 设置驱动数据，以便在回调函数中使用
    lv_display_set_driver_data(disp, (void *)(uintptr_t)fb_fd);

    // 设置显示缓冲区
    static lv_color_t buf1[SCREEN_HOR_RES * 10]; // 声明显示缓冲区
    lv_display_set_buffers(disp, buf1, NULL, sizeof(buf1), LV_DISPLAY_RENDER_MODE_PARTIAL);

    // 设置显示刷新回调函数
    lv_display_set_flush_cb(disp, fb_flush);

    // 设置颜色格式
    lv_display_set_color_format(disp, color_format);

    // 输入设备初始化
    static lv_indev_t *touch_indev;

    // 创建输入设备对象
    touch_indev = lv_indev_create();
    if (touch_indev == NULL) {
        printf("Failed to create input device\n");
        return;
    }

    // 设置输入设备类型
    lv_indev_set_type(touch_indev, LV_INDEV_TYPE_POINTER);

    // 设置读取回调函数
    lv_indev_set_read_cb(touch_indev, touchpad_read);

    // 设置用户数据（触摸屏文件描述符）
    int touch_fd = open("/dev/input/event6", O_RDONLY | O_NONBLOCK);
    if (touch_fd < 0) {
        perror("Failed to open touch device");
        // 注意：这里不返回错误，因为触摸屏可能不是必需的
    }
    lv_indev_set_user_data(touch_indev, (void *)(uintptr_t)touch_fd);

    // 将输入设备分配给显示设备
    lv_indev_set_display(touch_indev, disp);

    // 创建UI线程
    pthread_t ui_thread;
    int res = pthread_create(&ui_thread, NULL, ds_ui_page_thread, NULL);
    if (res != 0)
    {
        printf("pthread_create ds_ui_page_thread failed: %d\n", res);
        return;
    }
    
    printf("Camera application started successfully\n");
    
    // 不要等待UI线程结束，否则会阻塞主线程
    // pthread_join(ui_thread, NULL);
    
    // 分离线程，让它独立运行
    pthread_detach(ui_thread);
}
